package training.sample.app.web;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import training.sample.app.domain.Client;
import training.sample.app.domain.Country;
import training.sample.app.domain.UserAccount;
import training.sample.app.service.ClientService;
import training.sample.app.service.CountryService;
import training.sample.app.service.UserService;

@Controller
@RequestMapping("/client")
public class ClientController {

	@Autowired
	private ClientService clientService;
	
	@Autowired
	private CountryService countryService;
	
	@Autowired
	private UserService userService;

	@PreAuthorize("isFullyAuthenticated() and hasAnyRole('ROLE_ADMIN','ROLE_USER')")
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ModelAndView listClients(HttpSession session) {

		ModelAndView mav = new ModelAndView();
		mav.addObject("clients", clientService.getClients());
		
		Object userObject = session.getAttribute("user");
		if ((userObject != null) && (userObject instanceof UserAccount)) {
			UserAccount user = (UserAccount) userObject;
			
			mav.addObject("user.name", user.getName());
		}
		
		mav.setViewName("client.list");
		return mav;
	}
	
	@PreAuthorize("isFullyAuthenticated() and hasAnyRole('ROLE_ADMIN','ROLE_USER')")
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public String showUserProfile(
			@PathVariable("id") Client client,
			HttpSession session, Model model) {

		model.addAttribute("client", client);
		
		return "client.details";
	}

	@PreAuthorize("isFullyAuthenticated() and hasRole('ROLE_ADMIN')")
	@RequestMapping(value = "/new", method = RequestMethod.GET)
	public ModelAndView newClientForm(Model model) {

		populateControls(model);
		
		model.addAttribute("client", new Client(0L, "Enter Client Name", "Enter SSN"));
		model.addAttribute("action", "new");
		
		ModelAndView mav = new ModelAndView();
		mav.setViewName("client.form");
		return mav;
	}	

	@PreAuthorize("isFullyAuthenticated() and hasRole('ROLE_ADMIN')")
	@RequestMapping(value = "/new", method = RequestMethod.POST)
	public String newClientSubmit(
			@Valid @ModelAttribute Client client, 
			BindingResult result, Model model) {
		
		String view = "client.list";
		
		if (result.hasErrors()) {
			populateControls(model);
			view = "client.form";
		} else {
			if (client != null) {
				clientService.saveClient(client);			
				model.addAttribute("clients", clientService.getClients());
			}
			model.asMap().remove("client");
		}

		return view;
	}
	
	@PreAuthorize("isFullyAuthenticated() and hasRole('ROLE_ADMIN')")
	@RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
	public String editClientForm(
			@PathVariable("id") Client client,
			HttpSession session, Model model) {

		populateControls(model);
		
		client.setSingleChoice("A2");
		client.setMultipleOptions(new String[] {"M1", "M4"} );
		
		model.addAttribute("client", client);
		model.addAttribute("action", client.getId());

		return "client.form.edit";
	}	

	@PreAuthorize("isFullyAuthenticated() and hasRole('ROLE_ADMIN')")
	@RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
	public String editClientSubmit(
			@Valid @ModelAttribute Client client, 
			BindingResult result,
			@RequestParam(value = "country") String countryCode,
			@RequestParam(value = "multipleOptions") String[] options,
			Model model) {
		
		String view = "client.list";
		
		if (result.hasErrors()) {
			populateControls(model);
			view = "client.form.edit";
		} else {
			if (client != null) {
				System.out.println("active:" + client.isActive());
				
				System.out.print("multipleOptions:");
				for(String item : client.getMultipleOptions()) {
					System.out.print(item + ", ");	
				}
				System.out.println("");
				
				System.out.println("singleChoice:" + client.getSingleChoice());
				System.out.println("notes:" + client.getNotes());
				System.out.println("country:" + client.getCountry());
				
				System.out.print("businessFields:");
				for(String item : client.getBusinessFields()) {
					System.out.print(item + ", ");	
				}
	
				clientService.updateClient(client);			
				model.addAttribute("clients", clientService.getClients());
			}
			
			model.asMap().remove("client");
		}
		return view;
	}
	
	@RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
	public String deleteClient(
			@PathVariable("id") Client client,
			HttpSession session, Model model) {
		
		clientService.deleteClient(client);			
		model.addAttribute("clients", clientService.getClients());
		
		return "client.list";
	}
	
	private void populateControls(Model model) {
		
		Map<String, String> countryList = new LinkedHashMap<String, String>();
		List<Country> countries = countryService.getCountries();
		for (Country c: countries) {
			countryList.put(c.getId().toString(), c.getName());
		}
		model.addAttribute("countryList", countryList);
		
		Map<String, String> multipleOptionsList = new LinkedHashMap<String, String>();
		multipleOptionsList.put("M1", "Option M1");
		multipleOptionsList.put("M2", "Option M2");
		multipleOptionsList.put("M3", "Option M3");
		multipleOptionsList.put("M4", "Option M4");
		model.addAttribute("multipleOptionsList", multipleOptionsList);
 
		Map<String, String> businessFieldList = new LinkedHashMap<String, String>();
		businessFieldList.put("BF1", "Business Field 1");
		businessFieldList.put("BF2", "Business Field 2");
		businessFieldList.put("BF3", "Business Field 3");
		businessFieldList.put("BF4", "Business Field 4");
		model.addAttribute("businessFieldList", businessFieldList);
	}
}